#pragma once

#include <mutex>
#include <iostream>
#include <pthread.h> //这个头文件是 C语言风格 pthread_mutex_t 类似这样的类型

namespace MyMutex
{
    class Mutex // 锁是不支持拷贝的！
    {

    private:
        pthread_mutex_t _lock; // 这个是锁

    public:
        Mutex(const Mutex &_mutex) = delete;            // 锁不支持拷贝构造和赋值构造
        const Mutex &operator=(const Mutex &) = delete; // 锁不支持拷贝构造和赋值构造
        Mutex()
        {
            if (::pthread_mutex_init(&_lock, nullptr) != 0) // 以 pthread_开头的函数成功返回值基本上都是0  失败基本上都是 错误码
            {
                std::cout << "Mutex() 失败!" << std::endl;
            }
        }
        pthread_mutex_t *LockPtr()
        {
            return &_lock;
        }

        ~Mutex()
        {
            if (::pthread_mutex_destroy(&_lock) != 0) //
            {
                std::cout << "~Mutex() 失败!" << std::endl;
            }
        }

        void Lock()
        {
            if (::pthread_mutex_lock(&_lock) != 0) //
            {
                std::cout << "Lock() 失败!" << std::endl;
            }
        }

        void Unlock()
        {
            if (::pthread_mutex_unlock(&_lock) != 0) //
            {
                std::cout << "Unlock() 失败!" << std::endl;
            }
        }
    };

    class LockGuard
    {
    private:
        Mutex &_mutex;

    public:
        LockGuard(Mutex &_out_mutex) : _mutex(_out_mutex)
        {
            _mutex.Lock(); // 这里实现的是加锁
        }
        ~LockGuard()
        {
            _mutex.Unlock(); // 这里实现的是解锁
        }
    };
}

// pthread_mutex_init   pthread_mutex_destroy  pthread_mutex_lock  pthread_mutex_unlock